package org.springblade.modules.digitalization.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.StyleSet;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellUtil;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.modules.digitalization.entity.ManageRsdamlEntity;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class ExcelExportUtil {

	public static final int COL_COUNT = 7;
	public static final int MAX_DATA_ROW_COUNT = 17;
	// 最大材料名称宽度
	public static final int MAX_CHAR_LENGTH_IN_NAME = 21;
	// 最大备注宽度
	public static final int MAX_CHAR_LENGTH_IN_REMARK = 5;
	// 最大材料类别宽度
	public static final int MAX_CHAR_LENGTH_IN_CATEGORY_NAME = 16;

	public static final int BASE_HEIGHT = 35;
	private static final int HEIGHT_PER_LINE = 15;


	@Data
	private static class RowConfig {

		public boolean isCategoryRow = false;

		public boolean isEmptyRow = false;

		public int hegiht = BASE_HEIGHT;

		@Builder
		public RowConfig(boolean isCategoryRow, boolean isEmptyRow, int hegiht) {
			this.isCategoryRow = isCategoryRow;
			this.isEmptyRow = isEmptyRow;
			this.hegiht = hegiht;
		}
	}

	/**
	 * 获取字符的估算宽度（以“字符宽单位”为基准）
	 */
	private static double getCharWidth(char c) {
		if (c == '\t') return 1.0;
		if (c == ' ') return 0.5;

		if (isChinese(c)) return 1.0;
		if (isFullWidthPunctuation(c)) return 1.0;
		if (Character.isUpperCase(c)) return 0.6;
		if (Character.isLowerCase(c)) return 0.5;
		if (Character.isDigit(c)) return 0.5;
		return 0.5; // 默认半角符号
	}

	/**
	 * 判断是否为中文（CJK）
	 */
	private static boolean isChinese(char c) {
		return String.valueOf(c).matches("[\\u4e00-\\u9fa5]");
	}

	/**
	 * 判断是否是全角标点（中文标点）
	 */
	private static boolean isFullWidthPunctuation(char c) {
		return "，。、！？【】（）《》“”‘’；：".indexOf(c) != -1;
	}

	/**
	 * 根据字符估算总行高
	 *
	 * @param text           内容文本
	 * @param maxCharPerLine 每行最大“字符宽单位”
	 * @return 行高（单位：1/20 pt，用于 setRowHeight）
	 */
	public static short estimateRowHeight(String text, int maxCharPerLine) {
		if (text == null || text.isEmpty()) {
			return (short) BASE_HEIGHT;
		}

		int lineCount = 1;
		double currentLineWidth = 0.0;

		for (char c : text.toCharArray()) {
			if (c == '\n') {
				lineCount++;
				currentLineWidth = 0;
				continue;
			}

			double charWidth = getCharWidth(c);
			currentLineWidth += charWidth;

			if (currentLineWidth > maxCharPerLine) {
				lineCount++;
				currentLineWidth = charWidth;
			}
		}
		lineCount -= 2;
		lineCount = Math.max(lineCount, 0);
		// 从第二行开始增加行高
		int totalHeight = BASE_HEIGHT + lineCount * HEIGHT_PER_LINE;
		return (short) totalHeight;
	}


	public static void exportData(List<ManageRsdamlEntity> pages, List<Map<String, String>> dict, String personName,
								  String filePath, String config) {
		File file = new File(filePath);
		if (FileUtil.exist(file)) {
			FileUtil.del(file);
		}
		List<Pair<RowConfig, List<String>>> rows = CollUtil.newArrayList();
		dict.forEach(dictEntity -> {
			String dictKey = dictEntity.get("dictKey");
			String dictValue = dictEntity.get("dictValue");
			dictValue = dictValue.substring(dictKey.length() + 1);
			boolean hasSub = StringUtils.equals(dictEntity.get("hasSub"), "true");

			int rowHeight0 = estimateRowHeight(dictValue, MAX_CHAR_LENGTH_IN_CATEGORY_NAME);
			rows.add(Pair.of(RowConfig.builder().hegiht(rowHeight0).isCategoryRow(true).build(),
				CollUtil.newArrayList(dictKey, dictValue, "", "", "", "", "")));
			if (hasSub == false) {
				List<ManageRsdamlEntity> list = getByCategoryCode(pages, dictKey);
				list.forEach(manageRsdamlEntity -> {
					String year = "", month = "", day = "";
					if (StringUtils.isNotBlank(manageRsdamlEntity.getRsdaml006())) {
						year = manageRsdamlEntity.getRsdaml006();
					}
					if (StringUtils.isNotBlank(manageRsdamlEntity.getRsdaml007())) {
						month = manageRsdamlEntity.getRsdaml007();
					}
					if (StringUtils.isNotBlank(manageRsdamlEntity.getRsdaml008())) {
						day = manageRsdamlEntity.getRsdaml008();
					}
					String rsdaml009 = manageRsdamlEntity.getRsdaml009();
					// 散材料备注
					if (StringUtils.equals(rsdaml009, "SCL")) {
						rsdaml009 = "";
					}

					int rowHeight1 = estimateRowHeight(manageRsdamlEntity.getRsdaml004(), MAX_CHAR_LENGTH_IN_NAME);
					int rowHeight2 = estimateRowHeight(rsdaml009, MAX_CHAR_LENGTH_IN_REMARK);

					int rowHeight = Math.max(rowHeight1, rowHeight2);

					// 根据文字长度计算行高
					List<String> row = CollUtil.newArrayList(manageRsdamlEntity.getRsdaml003().toString(),
						manageRsdamlEntity.getRsdaml004(), year, month, day, manageRsdamlEntity.getRsdaml005().toString(),
						rsdaml009);
					rows.add(Pair.of(RowConfig.builder().hegiht(rowHeight).build(), row));
				});
				// 分类后面空一行
				rows.add(Pair.of(RowConfig.builder().hegiht(BASE_HEIGHT).build(), CollUtil.newArrayList("", "", "", "", "", "", "")));
			}
		});
		ExcelWriter writer = ExcelUtil.getWriter(filePath);
		List<List<Pair<RowConfig, List<String>>>> split = splitRows(rows);
		for (int i = 0; i < split.size(); i++) {
			creareNewSheet(writer, "目录整理" + i, personName, split.get(i), config);
		}
		writer.getWorkbook().removeSheetAt(0);
		writer.close();
	}

	private static List<List<Pair<RowConfig, List<String>>>> splitRows(List<Pair<RowConfig, List<String>>> rows) {
		int maxHeightPeerSheet = MAX_DATA_ROW_COUNT * BASE_HEIGHT;
		List<List<Pair<RowConfig, List<String>>>> result = Lists.newArrayList();

		List<Pair<RowConfig, List<String>>> currentSheetRows = Lists.newArrayList();
		int heightCount = 0;
		for (int i = 0; i < rows.size(); i++) {
			Pair<RowConfig, List<String>> rowConfigListPair = rows.get(i);
			int nextHeight = heightCount + rowConfigListPair.getKey().getHegiht();
			if (nextHeight > maxHeightPeerSheet) {
				result.add(currentSheetRows);
				currentSheetRows = Lists.newArrayList();
				heightCount = 0;
			}
			heightCount += rowConfigListPair.getKey().getHegiht();
			currentSheetRows.add(rowConfigListPair);
		}
		if (currentSheetRows.isEmpty() == false) {
			result.add(currentSheetRows);
		}
		return result;
	}

	private static List<ManageRsdamlEntity> getByCategoryCode(List<ManageRsdamlEntity> allEntity, String categoryCode) {
		List<ManageRsdamlEntity> collect = allEntity.stream()
			.filter(manageRsdamlEntity -> StringUtils.equals(categoryCode, manageRsdamlEntity.getRsdaml002()))
			.collect(Collectors.toList());
		return collect;
	}


	private static final List<String> title = CollUtil.newArrayList("干 部 人 事 档 案 目 录", "", "", "", "", "", "");
	private static final List<String> header = CollUtil.newArrayList("序号", "材  料  名  称", "材料形成时间", "", "", "页数", "备注");
	private static final List<String> date = CollUtil.newArrayList("", "", "年", "月", "日", "", "");

	private static void creareNewSheet(ExcelWriter writer, String sheet,
									   String personName, List<Pair<RowConfig, List<String>>> rows, String config) {

		writer.setSheet(sheet);
		Sheet currentSheet = writer.getSheet();

		if (StringUtils.isNotBlank(config)) {
			JSONObject jsonObject = JSON.parseObject(config);
			if (jsonObject.containsKey("lp")) {
				currentSheet.setMargin(PageMargin.LEFT, jsonObject.getDouble("lp") / 2.54d);
			}
			if (jsonObject.containsKey("rp")) {
				currentSheet.setMargin(PageMargin.RIGHT, jsonObject.getDouble("rp") / 2.54d);
			}
			if (jsonObject.containsKey("tp")) {
				currentSheet.setMargin(PageMargin.TOP, jsonObject.getDouble("tp") / 2.54d);
			}
			if (jsonObject.containsKey("bp")) {
				currentSheet.setMargin(PageMargin.BOTTOM, jsonObject.getDouble("bp") / 2.54d);
			}

		}

		List<String> name = CollUtil.newArrayList("姓名：" + personName, "", "", "", "", "", "");

		//通过构造方法创建writer
		writer.writeHeadRow(title);
		writer.merge(0, 0, 0, COL_COUNT - 1, null, false);

		writer.writeHeadRow(name);
		writer.merge(1, 1, 0, COL_COUNT - 1, null, false);

		writer.writeHeadRow(header);
		writer.writeHeadRow(date);

		writer.merge(2, 3, 0, 0, null, false);
		writer.merge(2, 3, 1, 1, null, false);
		writer.merge(2, 2, 2, 4, null, false);
		writer.merge(2, 3, 5, 5, null, false);
		writer.merge(2, 3, 6, 6, null, false);

		List<List<String>> strRows = rows.stream().map(Pair::getValue).collect(Collectors.toList());
		// 写入数据
		writer.write(strRows, true);

		// 设置行高，列宽
		writer.setColumnWidth(0, 7);
		writer.setColumnWidth(1, 43);
		writer.setColumnWidth(2, 7);
		writer.setColumnWidth(3, 6);
		writer.setColumnWidth(4, 6);
		writer.setColumnWidth(5, 7);
		writer.setColumnWidth(6, 11);

		writer.setRowHeight(0, 46);
		writer.setRowHeight(1, 24);
		writer.setRowHeight(2, 24);
		writer.setRowHeight(3, 24);

		for (int i = 0; i < rows.size(); i++) {
			int rowHegiht = rows.get(i).getKey().hegiht;
			writer.setRowHeight(4 + i, rowHegiht);
		}

		StyleSet style = writer.getStyleSet();

		CellStyle cellStyle = style.getCellStyle();
		cellStyle.setBorderTop(BorderStyle.THIN);
		cellStyle.setBorderBottom(BorderStyle.THIN);
		cellStyle.setBorderLeft(BorderStyle.THIN);
		cellStyle.setBorderRight(BorderStyle.THIN);

		Font globalFont = createFont(writer, 11);
		style.setFont(globalFont, false);

		CellStyle headCellStyle = writer.getHeadCellStyle();
		headCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());

		Font headerFont = createFont(writer, 14);
		headCellStyle.setFont(headerFont);

		Font titleFont = createFont(writer, 24);
		for (int i = 0; i < COL_COUNT; i++) {
			Cell titleCell = writer.getCell(i, 0);
			CellUtil.setCellStyleProperty(titleCell, CellUtil.FONT, titleFont.getIndex());
			CellUtil.setCellStyleProperty(titleCell, CellUtil.BORDER_TOP, BorderStyle.NONE);
			CellUtil.setCellStyleProperty(titleCell, CellUtil.BORDER_BOTTOM, BorderStyle.NONE);
			CellUtil.setCellStyleProperty(titleCell, CellUtil.BORDER_LEFT, BorderStyle.NONE);
			CellUtil.setCellStyleProperty(titleCell, CellUtil.BORDER_RIGHT, BorderStyle.NONE);
		}

		Font nameFont = createFont(writer, 12);
		for (int i = 0; i < COL_COUNT; i++) {
			Cell nameCell = writer.getCell(i, 1);
			CellUtil.setCellStyleProperty(nameCell, CellUtil.FONT, nameFont.getIndex());
			CellUtil.setCellStyleProperty(nameCell, CellUtil.BORDER_TOP, BorderStyle.NONE);
			CellUtil.setCellStyleProperty(nameCell, CellUtil.BORDER_LEFT, BorderStyle.NONE);
			CellUtil.setCellStyleProperty(nameCell, CellUtil.BORDER_RIGHT, BorderStyle.NONE);
			CellUtil.setAlignment(nameCell, HorizontalAlignment.LEFT);
		}

		for (int i = 0; i < rows.size(); i++) {
			int rowIndex = 4 + i;
			// 第二列左对齐
			Cell fileNameCell = writer.getCell(1, rowIndex);
			CellUtil.setAlignment(fileNameCell, HorizontalAlignment.LEFT);
			CellUtil.setCellStyleProperty(fileNameCell, CellUtil.WRAP_TEXT, true);


			Cell remarkCell = writer.getCell(6, rowIndex);
			CellUtil.setAlignment(remarkCell, HorizontalAlignment.LEFT);
			CellUtil.setCellStyleProperty(remarkCell, CellUtil.WRAP_TEXT, true);

			if (rows.get(i).getKey().isCategoryRow) {
				for (int j = 0; j < COL_COUNT; j++) {
					Cell cell = writer.getCell(j, rowIndex);
					CellUtil.setCellStyleProperty(cell, CellUtil.FONT, headerFont.getIndex());
				}
			}
			for (int j = 0; j < 6; j++) {
				Cell cell = writer.getCell(j, rowIndex);
				String stringCellValue = cell.getStringCellValue();
				if (j == 3 || j == 4) {
					if (StringUtils.isNotBlank(stringCellValue) && ReUtil.isMatch("\\d+", stringCellValue.trim())) {
						CellUtil.setCellStyleProperty(cell, CellUtil.FONT, globalFont.getIndex());
					}
				} else {
					if (StringUtils.isNotBlank(stringCellValue) && ReUtil.isMatch("\\d+", stringCellValue.trim())) {
						cell.setCellValue(NumberUtil.parseInt(stringCellValue));
						CellUtil.setCellStyleProperty(cell, CellUtil.FONT, globalFont.getIndex());
					}
				}
			}
		}
	}

	private static Font createFont(ExcelWriter writer, int size) {
		Font font = writer.createFont();
		font.setFontHeightInPoints((short) size);
		font.setBold(true);
		font.setFontName("宋体");
		return font;
	}

	private static boolean checkNumber(String number, int min, int max) {
		try {
			int i = NumberUtil.parseInt(number);
			return i >= min && i <= max;
		} catch (Exception e) {
			return false;
		}
	}

	public static Triple<String, String, String> getDate(String formationTime) {

		String year, month, day;
		year = StrUtil.sub(formationTime, 0, 4);
		if (checkNumber(year, 0, 9999) == false) {
			throw new ServiceException("年份错误：" + year);
		}
		if (StringUtils.equals(year, "0000")) {
			year = "";
		}

		month = StrUtil.sub(formationTime, 4, 6);
		if (checkNumber(month, 0, 12) == false) {
			throw new ServiceException("月份错误：" + year);
		}
		if (StringUtils.equals(month, "00")) {
			month = "";
		}

		day = StrUtil.sub(formationTime, 6, 8);
		if (checkNumber(day, 0, 31) == false) {
			throw new ServiceException("天错误：" + year);
		}
		if (StringUtils.equals(day, "00")) {
			day = "";
		}
		return Triple.of(year, month, day);

	}

	public static void main(String[] args) {
		String s = StringUtils.leftPad("1", 1, "0");
		System.out.println(s);
	}

}
